import os
import re
import pandas as pd
import time
from docx import Document
from docx.shared import Cm
from datetime import datetime

# 定义文件夹路径（使用原始字符串）
folder_path = r'D:\study\python\123\黄埔内部'
unique_numbers = set()
number_to_filenames = {}
missing_images = []  # 用于记录缺失的图片
unknown_point_names = []  # 用于记录未知点位名称的编号
normal_numbers = []  # 用于记录正常的编号（图片齐全）
missing_numbers = []  # 用于记录缺少图片的编号


def log_message(message, log_file):
    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    log_str = f"[{timestamp}] {message}"
    print(log_str)  # 控制台打印
    log_file.write(log_str + "\n")  # 写入日志文件


# 提取编号和文件名，并存储路径
for filename in os.listdir(folder_path):
    if filename.lower().endswith('.jpg'):
        # 匹配 'LHu'（不区分大小写）后跟一组数字，用非数字字符（包括空格、顿号、感叹号等）分隔
        match = re.search(r'LHu([\d]+(?:[^\d]+[\d]+)*)', filename, re.IGNORECASE)

        if match:
            number_with_separators = match.group(1)
            # 将数字按非数字字符分隔
            number_strings = re.split(r'\D+', number_with_separators)

            for num_str in number_strings:
                if num_str:
                    num = int(num_str)
                    unique_numbers.add(num)

                    filtered_filename = re.sub(r' LHu.*(?=\.jpg$)', '', filename, flags=re.IGNORECASE).strip()

                    if num not in number_to_filenames:
                        number_to_filenames[num] = []
                    number_to_filenames[num].append(filtered_filename)

print(f"提取完成，共找到 {len(unique_numbers)} 个唯一的编号。")

# 编号格式化
prefixed_numbers = [f"HPCZC-LHu-JK{num:03d}" for num in unique_numbers]

# 加载 Excel 文件
excel_path = r'C:\Users\Ading\Desktop\点位.xlsx'
df = pd.read_excel(excel_path)

# 处理点位名称，去掉 * 字符，确保匹配时不受影响
location_dict = {row['图纸编号']: row['点位名称'].replace('\n', '').replace('\r', '') for _, row in df.iterrows()}

# Word 模板路径和输出文件夹
template_path = r'C:\Users\Ading\Desktop\HPCZC-LHu-JK.docx'
output_folder = r'C:\Users\Ading\Desktop\test1'
log_file_path = r'C:\Users\Ading\Desktop\processing_log.txt'  # 日志文件路径

if not os.path.exists(output_folder):
    os.makedirs(output_folder)

# 记录总开始时间
start_time = time.time()

# 创建日志文件
log_file = open(log_file_path, 'w', encoding='utf-8')

# 写入日志文件头
log_file.write("处理日志\n")
log_file.write("=" * 50 + "\n")


# 图片插入函数
def insert_image(doc, image_path, marker, height):
    marker_found = False
    for table in doc.tables:
        for row in table.rows:
            for cell in row.cells:
                if marker in cell.text:
                    marker_found = True
                    cell.text = cell.text.replace(marker, '')  # 去掉标志文字
                    run = cell.paragraphs[0].add_run()
                    run.add_picture(image_path, height=height)
                    cell.paragraphs[0].alignment = 1  # 1 表示居中对齐
                    log_message(f"插入图片: {image_path} 到标志: {marker}", log_file)  # 添加标志插入日志
                    break
            if marker_found:
                break
        if marker_found:
            break

    if not marker_found:
        log_message(f"标志 {marker} 未在表格中找到，未插入图片。", log_file)


# 定义图片高度
markers = ['SBXW', 'SBXN', 'QJT1', 'QJT2', 'QDD']
height_mapping = {
    'QJT1': Cm(6.5),
    'QJT2': Cm(6.5),
    'SBXW': Cm(6.5),
    'SBXN': Cm(6.5),
    'QDD': Cm(6.5),
}


# 函数：根据时间字符串递减秒数
def decrement_seconds(filename):
    # 正则匹配时间部分
    match = re.search(r'(\d{4}_\d{2}_\d{2} \d{2}_\d{2}_(\d{2}))', filename)
    if match:
        # 获取时间字符串中的小时、分钟、秒部分
        time_parts = match.group(0).split(' ')  # '2024_10_27 17_06_29'
        date_str = time_parts[0]  # '2024_10_27'
        time_str = time_parts[1]  # '17_06_29'

        # 分割时间部分为小时、分钟、秒
        hour, minute, second = map(int, time_str.split('_'))

        # 减去1秒
        if second > 0:
            second -= 1
        else:
            second = 59
            if minute > 0:
                minute -= 1
            else:
                minute = 59
                if hour > 0:
                    hour -= 1
                else:
                    hour = 23  # 如果小时也为0，表示跨天

        # 重新构建时间字符串
        new_time_str = f"{hour:02}_{minute:02}_{second:02}"
        new_filename = filename.replace(time_str, new_time_str)
        return new_filename
    return filename


# 查找点位名称的函数，包含尝试加 * 的逻辑
def get_point_name(prefixed_num):
    # 先查找原编号
    point_name = location_dict.get(prefixed_num, None)
    if point_name:
        return point_name

    # 如果找不到，再尝试加 * 后查找
    point_name = location_dict.get(f"{prefixed_num}*", None)
    if point_name:
        return point_name

    # 如果都找不到，返回 "未知名称"
    return "未知名称"


# 遍历每个编号，生成 Word 文件
for idx, prefixed_num in enumerate(prefixed_numbers):
    log_message(f"\n\n正在处理第 {idx + 1}/{len(prefixed_numbers)} 个编号：{prefixed_num}", log_file)

    # 获取点位名称
    point_name = get_point_name(prefixed_num)
    if point_name == "未知名称":
        unknown_point_names.append(prefixed_num)  # 添加到未知点位名称列表
    else:
        log_message(f"编号 {prefixed_num} 对应的点位名称: {point_name}", log_file)

    doc = Document(template_path)

    # 替换点位编号和点位名称
    for para in doc.paragraphs:
        if '点位图纸编号' in para.text:
            para.text = para.text.replace('num', prefixed_num)
        if '点位名称' in para.text:
            para.text = para.text.replace('name', point_name)

    filenames = number_to_filenames.get(int(prefixed_num[-3:]), [])
    log_message(f"当前编号 {prefixed_num} 对应的图片文件名列表:\n" + "\n".join(filenames), log_file)

    # 插入图片
    for marker, filename in zip(markers, filenames):
        image_path = os.path.join(folder_path, filename)

        # 判断图片文件是否存在
        if os.path.exists(image_path):
            log_message(f"图片路径: {image_path} 存在，准备插入图片。", log_file)
            height = height_mapping.get(marker, Cm(7))
            insert_image(doc, image_path, marker, height)
        else:
            log_message(f"图片路径: {image_path} 不存在！", log_file)
            # 尝试减去1秒并检查新的文件名
            new_filename = decrement_seconds(filename)
            new_image_path = os.path.join(folder_path, new_filename)

            if os.path.exists(new_image_path):
                log_message(f"尝试减去1秒，新的文件名：{new_filename} 找到图片，准备插入。", log_file)
                insert_image(doc, new_image_path, marker, height)
            else:
                # 尝试再次减去1秒并检查新的文件名
                new_filename = decrement_seconds(new_filename)
                new_image_path = os.path.join(folder_path, new_filename)
                if os.path.exists(new_image_path):
                    log_message(f"尝试减去1秒，新的文件名：{new_filename} 找到图片，准备插入。", log_file)
                    insert_image(doc, new_image_path, marker, height)
                else:
                    # 尝试再次减去1秒并检查新的文件名
                    new_filename = decrement_seconds(new_filename)
                    new_image_path = os.path.join(folder_path, new_filename)
                if os.path.exists(new_image_path):
                    log_message(f"尝试再次减去1秒，新的文件名：{new_filename} 找到图片，准备插入。", log_file)
                    insert_image(doc, new_image_path, marker, height)
                else:
                    log_message(f"图片仍然不存在，最终文件名：{new_filename}", log_file)
                    missing_images.append(f"编号: {prefixed_num} 的图片 {filename} 不存在！")

    # 检查该编号的图片数量，如果少于5张，命名为“缺”字
    if len(filenames) < 5:
        new_file_name = os.path.join(output_folder, f'{prefixed_num}缺.docx')
        log_message(f"编号 {prefixed_num} 图片不足，文件名加 '缺' 字", log_file)
        missing_numbers.append(prefixed_num)
    else:
        new_file_name = os.path.join(output_folder, f'{prefixed_num}.docx')
        normal_numbers.append(prefixed_num)

    doc.save(new_file_name)
    log_message(f"保存文件：{new_file_name}", log_file)

# 汇总缺少图片的编号和正常编号
log_message("\n\n以下是处理结果汇总：", log_file)
if missing_numbers:
    log_message(f"\n以下编号图片数量不足，已加 '缺' 字：\n" + "\n".join(missing_numbers), log_file)
if normal_numbers:
    log_message(f"\n以下编号图片齐全：\n" + "\n".join(normal_numbers), log_file)

# 输出未知点位名称的编号
if unknown_point_names:
    log_message(f"\n以下点位编号没有找到对应名称：\n" + "\n".join(unknown_point_names), log_file)

# 输出缺失的图片信息
if missing_images:
    log_message(f"\n以下图片不存在：\n" + "\n".join(missing_images), log_file)

# 记录处理结束时间并输出总耗时
end_time = time.time()
elapsed_time = end_time - start_time
log_message(f"\n处理完成，总耗时：{elapsed_time:.2f}秒", log_file)

# 关闭日志文件
log_file.close()
